#ifndef _CGAMECORE_H
#define _CGAMECORE_H

#include <stdio.h>
#include <time.h>

#if defined(ANDROID_OS)
#include "../../_android/jni/jni_Util.h"
#endif

#if defined(MAC_OS)
#include <unistd.h>
#endif

#include "CType.h"
#include "../Define/Defines.h"
#include "../Lib/Sprite/CSprite.h"
#include "CDevice.h"
#include "CEvent.h"
#include "CTouch.h"
#include "../Lib/ArrayList/ArrayList.h"
#include "CByteBuffer.h"
#include "CG2D.h";



#include "../GamePlay/CGame_include_ex.h"



//define some tools
#define GX(x)	(((x) * CGame::_this->_game_scale) + CGame::_this->_game_x)
#define GY(y)	(((y) * CGame::_this->_game_scale) + CGame::_this->_game_y)
#define G(d)	((d) * CGame::_this->_game_scale)
#define DL		CGame::_this->_game_x
#define DT		CGame::_this->_game_y
#define GR		CGame::_this->_game_right
#define GBT		CGame::_this->_game_bottom
#define DR		CGame::_this->_game_dright
#define DBT		CGame::_this->_game_dbottom
#define DW		(DL+DR)
#define DH		(DT+DBT)
//define for sound manager
#if !defined(RES_NUM_SOUND)
#define RES_NUM_SOUND	10
#endif
//define for using event
#define THROW_EVENT(evt_code, data, len) CGame::_this->_e.put(evt_code, data,len)
#define GET_EVENT(pointer, evt_code) CGame::_this->_e.getEvents(pointer, evt_code)

extern "C" unsigned long OS_GetTime(void);

class CGame
{

public:
	bool			_isExit;
	bool			_isPause;
	//device
	CDevice			_d;
	//game
	static CGame*	_this;
	
	//graphics
	GLESLib*		_g;
	
	//input & output
	//#define 				IO_BUFFER_LENGTH	1024
	UINT32					_output_offset;
	BYTE*					_output_buffer;
	
	//game's event manager
	CEventManager _e;
	//game's sprite
	CSprite		_sprite;
	int 			_num_sprites;

	//text
	UNICHAR*** 		_texts;
	UINT16** 		_text_lens;

	//game state
	int				_GameState;
	int				_GameSubState;
	int				_GameStateNew;
	int				_GameStateOld;
	
	//touch control
	CTouch**		_touches;
	int				_num_touches;
	static UINT32	_touch_id_gen;
	int				_active_touch;
	
	//phone orientation
	int				_game_orientation;
	float			_game_scale_w;
	float			_game_scale_h;
	float			_game_scale;
	int				_game_x;
	int				_game_y;
	int				_game_right;
	int				_game_bottom;
	int				_game_dright;
	int				_game_dbottom;
	//control fps
	UINT32			_last_frame_time;
	UINT32			_frame_dt;
	UINT32			_run_time;
	UINT32			_frame_counter;
private:
	UINT32			_fps_time_limit;
public:
	CGame(CDevice device);
static CGame* GetInstace(CDevice device);
	~CGame();
	
	void Init();
	void Release();
	
	void InitEx();
	void ReleaseEx();
	
	//game update and render function
	void UpdateAndRender();
	void UpdateTouch(int xx, int yy, int touch_state, int touch_id, int tap_count);
    void PauseEx();    
    void ResumeEx();
	void FlushGraphics();
	void Run();
	void Pause();
	void Resume();
	void Exit();
	void ProcessSytemEvents();
	static unsigned long GetTime()
	{
		return OS_GetTime();
	}

	static void Sleep(int iTime)
	{
		//printf("sheep %d ", iTime);
#ifdef MAC_OS
		usleep(iTime*1000);
#elif defined(QT_CREATOR) || defined(ANDROID_OS)
        OS_Sleep(iTime);
#else
		SleepEx(iTime, 1);
#endif
	}
	
	static struct tm* GetDateTime()
	{
		time_t rawtime;
		time(&rawtime);
		
		return localtime(&rawtime);
	}
	
	//game state function
	void SetGameState(int iNewState, bool isCleaning);
	void SetSubState(int iNewSubState);
		
	//load, unload and get sprite
	void LoadSprite();
	//void UnloadSprite();
	
	//free io buff
	void FreeOutputBuffer();
	
	//grapphic
	void LoadDesigner(int  designer_id);
	//logic touch
	void NotifyTouchesBegan(int touch_id, int x, int y, int tap_count);
	void NotifyTouchesMoved(int touch_id, int x, int y, int tap_count);
	void NotifyTouchesEnd(int touch_id, int x, int y, int tap_count);
	
	void ClearTouchesEnd();
    void ClearAllTouch();

	//include CGame_GamePlay.h which contain specific vars and methods for each game title
	#include "../GamePlay/CGame_prototype_ex.h"
};

#endif//_H_GAMECORE